package com.pnnd.stream;

import com.pnnd.utils.CollectionUtils;
import com.pnnd.utils.MemoryUtils;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;

public class ReadWriteBuffer extends AbstractBuffer {

    private InputStream inputStream;
    private OutputStream outputStream;

    @Override
    protected byte[] getByteAddress() {
        return new byte[0];
    }

    @Override
    public InputStream getInputStream() {
        if(this.inputStream != null){
            return this.inputStream;
        }

        this.inputStream = new NdArrayInputStream(this.segments){

        };

        return this.inputStream;
    }

    @Override
    public OutputStream getOutputStream() {

        if(this.outputStream != null){
            return this.outputStream;
        }

        this.outputStream = new NdArrayOutputStream(this.segments,this.offset,this.limit){
            @Override
            protected void innerFlush(int offset){
                ReadWriteBuffer.this.offset = offset;
                if(ReadWriteBuffer.this.inputStream instanceof Refreshable){
                    ((Refreshable) ReadWriteBuffer.this.inputStream).refresh(offset);
                }
            }
        };

        return this.outputStream;
    }

    @Override
    public void refresh(int offset) {
        this.offset = offset;
    }

    @Override
    public int getOffset() {
        return this.offset;
    }

    @Override
    public Collection<MemorySegment> getAll() {
        return CollectionUtils.readonly(this.segments);
    }

    @Override
    public MemorySegment get(int index) {
        return this.segments.get(index);
    }

    @Override
    public boolean isContinuous() {
        MemorySegment lastSegment = null;
        for(MemorySegment segment:this.segments){
            if(lastSegment != null && !MemoryUtils.isContinuous(lastSegment,segment)){
                return false;
            }
            lastSegment = segment;
        }
        return true;
    }
}
